查看原文
其他

精通Linux系列十二:从两个1000000行的文件里找出差异行(文件比较)

拾叁 更AI 2023-10-21

精通Linux系列点击关注公众号,AI&编程干货及时送达   


文件比较

命令含义
diff比较两个文件或目录的逐行差异。
comm比较两个已排序文件的逐行差异。
cmp比较两个文件的逐字节差异。
md5sum计算给定文件的校验和(MD5)。

在Linux中有三种方法可以比较文件:

  • • 逐行比较 (diffdiff3sdiffcomm),最适合文本文件

  • • 逐字节比较 (cmp),通常用于二进制文件

  • • 通过比较校验和进行比较 (md5sumsumcksum)

diff

stdin  stdout  - file  -- opt  --help  --version

diff [选项] file1 file2

diff命令逐行比较两个文件(或两个目录)。当比较文本文件时,diff可以生成详细的差异报告。对于二进制文件,diff只会报告它们是否有差异。对于所有文件,如果没有差异,diff不会产生任何输出。

传统的输出格式如下:

指示行号和更改类型
< 文件1的对应部分(如果有的话)
> 文件2的对应部分(如果有的话)

例如,如果我们开始一个叫fileA的文件:

你好,这是一个很棒的文件。
快速的棕色狐狸跳过了
懒狗。
再见。

假设我们删除了第一行,将第二行的"棕色"改为"蓝色",并添加了一行,生成一个叫fileB的文件:

快速的蓝色狐狸跳过了
懒狗。
再见。
Linux是最棒的!

那么diff命令会为这些文件生成如下输出:

 diff fileA fileB
1,2c1                  fileA的第1-2行变成了fileB的第1
< 你好,这是一个很棒的文件。   fileA的第1-2
< 快速的棕色狐狸跳过了
```    diff分隔符                              
> 快速的蓝色狐狸跳过了     fileB的第1行
4a4                         在fileB中添加了第4行
> Linux是最棒的!                       添加的行

前导符号<和>是箭头,分别指示fileAfileB。这个输出格式是默认的:还有许多其他可用的选项,其中一些可以直接供给其他工具使用。

选项输出格式
-nRCS版本控制格式,由rcsdiff(man rcsdiff)产生。
-c上下文差异格式,被patch命令(man patch)使用。
-D C预处理器格式,使用#ifdef  ... #else ... #endif
-u统一格式,合并文件并在删除前添加“-”,在添加时添加“+”。
-y并排格式;使用-W来调整输出的宽度。
-e创建一个ed脚本,如果运行,会将fileA变成fileB
-q不报告更改,只是说文件是否有差异。

diff也可以比较目录:

 diff dir1 dir2

这将比较这些目录中的任何同名文件,并列出所有出现在一个目录中但不在另一个目录中的文件。要递归比较整个目录层次结构,使用-r选项:

 diff -r dir1 dir2

这将产生一个(可能巨大的)所有差异的报告。

有用的选项

-b不考虑空格。
-B不考虑空行。
-i忽略大小写。
-r在比较目录时,递归进入子目录。

diff只是一个操作文件差异的程序家族中的一个成员。其他的一些成员包括diff3,一次比较三个文件,以及sdiff,根据你的指示将两个文件的差异合并到第三个文件中。

comm

stdin  stdout  - file  -- opt  --help  --version

comm [选项] 文件1 文件2

comm命令比较两个已排序的文件,并产生三列输出,由制表符分隔:

  1. 1. 所有出现在文件1中但不在文件2中的行。

  2. 2. 所有出现在文件2中但不在文件1中的行。

  3. 3. 在两个文件中都出现的所有行。

例如,如果commfile1commfile2包含以下行:

commfile1:               commfile2:
苹果            面包师傅
面包师傅            查理
查理          黑暗

然后comm产生这个三列的输出:

 comm commfile1 commfile2
苹果
                面包师傅
                查理
        黑暗

有用的选项

-1抑制第1列。
-2抑制第2列。
-3抑制第3列。
-23只显示出现在第一个文件中的行。
-13只显示出现在第二个文件中的行。
-12只显示公共行。

cmp

标准输入 标准输出  - 文件  -- 选项  --帮助  --版本

cmp [选项] 文件1 文件2 [偏移量1 [偏移量2]]

cmp命令比较两个文件。如果它们的内容相同,cmp不报告任何东西;否则,它列出第一个差异的位置:

 cmp 我的文件 你的文件
我的文件 你的文件有差异:字节225,行4

默认情况下,cmp不告诉你差异是什么,只告诉你差异在哪里。它也非常适合比较二进制文件,与diff不同,diff在处理文本文件时效果最好。

通常,cmp从每个文件的开始处开始比较,但如果你提供了偏移量,它会从其他地方开始:

 cmp 我的文件 你的文件 10 20

这在我的文件的第十个字符和你的文件的第二十个字符处开始比较。

有用的选项

-l长输出:打印所有差异,按字节打印:→ **cmp -l 我的文件 你的文件** 225 167 127这意味着在偏移量225(以十进制计),我的文件有一个小“w”(八进制167)但你的文件有一个大写的“W”(八进制127)。
-s静默输出:不打印任何东西,只是以一个适当的返回码退出;如果文件匹配,返回码为0,如果不匹配,返回码为1。(如果比较失败,可能会有其他代码。)

md5sum

标准输入 标准输出  - 文件  -- 选项  --帮助  --版本

md5sum 文件 | --check 文件

md5sum命令用校验和来验证文件是否未改变。第一种形式使用MD5算法产生给定文件的32字节校验和:

 md5sum 我的文件
48760f921ec6111e3979efa14e22535d  我的文件

第二种形式测试校验和是否与其文件匹配,使用--check

 md5sum 我的文件 我的文件2 我的文件3 > 我的总和
 cat 我的总和
48760f921ec6111e3979efa14e22535d  我的文件
49f6c28a5ec01d15703794a31accd08d  我的文件2
d28b9f7fc7d61c60913c8026fc91149a  我的文件3
 md5sum --check 我的总和
我的文件: OK
我的文件2: OK
我的文件3: OK
 echo "新数据" > 我的文件2
 md5sum --check 我的总和
我的文件: OK
我的文件2: 失败
我的文件3: OK
md5sum: 警告:3个计算的校验和有1个不匹配

两个不同的文件极不可能有相同的MD5校验和,所以比较校验和是检测两个文件是否不同的一个相当可靠的方式:

 md5sum 我的文件 | cut -c1-32 > 总和1
 md5sum 我的文件2 | cut -c1-32 > 总和2
 diff -总和1 总和2
总和1和总和2有差异

一个更强大但(暂时)不太受欢迎的程序是shasum,它可以使用不同的算法生成更长的哈希。它可能比md5sum更可靠。

 shasum 我的文件                    SHA-1算法
253c9c5836261859a77f83dc296168b35c1230ac  我的文件
 shasum -256 我的文件             SHA-256算法
e8183aaa23aa9b74c7033cbc843041fcf1d1e9e93724b7ef63c94d4c50a15df8 我的文件
 shasum 我的文件 > 我的总和
 shasum --check 我的总和
我的文件: OK

推荐阅读

··································

你好,我是拾叁,7年开发老司机、互联网两年外企5年。怼得过阿三老美,也被PR comments搞崩溃过。这些年我打过工,创过业,接过私活,也混过upwork。赚过钱也亏过钱。一路过来,给我最深的感受就是不管学什么,一定要不断学习。只要你能坚持下来,就很容易实现弯道超车!所以,不要问我现在干什么是否来得及。如果你还没什么方向,可以先关注我,这里会经常分享一些前沿资讯和编程知识,帮你积累弯道超车的资本。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存